package top.amot.forceview.force

import top.amot.forceview.layout.I_Layout

class ForceX : AbstractForce() {
    private lateinit var strengths: FloatArray
    private lateinit var xz: FloatArray
    private var xCalculation: NodeCalculation? = null
    private var strengthCalculation: NodeCalculation? = null
    override fun initialize(layout: I_Layout) {
        super.initialize(layout)
        initialize()
    }

    override fun apply(alpha: Float) {
        nodes.forEachIndexed { i, node ->
            node.vx += (xz[i] - node.x) * strengths[i] * alpha
        }

        /*for (i in nodes.indices) {
            val node = nodes[i]
            node.vx += (xz[i] - node.x) * strengths[i] * alpha
        }*/
    }

    fun x(c: NodeCalculation?): ForceX {
        xCalculation = c
        return this
    }

    fun strength(c: NodeCalculation?): ForceX {
        strengthCalculation = c
        return this
    }

    private fun initialize() {
        strengths = FloatArray(nodes.size)
        xz = FloatArray(nodes.size)
        for (i in nodes.indices) {
            xz[i] = x(i)
            strengths[i] = strength(i)
        }
    }

    private fun x(i: Int): Float {
        return xCalculation?.calculateNode(nodes[i])?:0f

    }

    private fun strength(i: Int): Float {
        return strengthCalculation?.calculateNode(nodes[i])?:DEFAULT_STRENGTH
    }

    companion object {
        const val NAME = "X"
        private const val DEFAULT_STRENGTH = 0.1f
    }
}